/*******************************************************************************
 * Level Master 2000
 * Copyright (C) 2010 Christian Herzog
 * For more information see http://code.google.com/p/levelmaster2000/
 *
 * This file is licensed under the terms of the MIT license, see
 * http://www.opensource.org/licenses/mit-license.php for further information.
 ******************************************************************************/

#ifndef PROPERTY_CHANGE_COMMAND_H
#define PROPERTY_CHANGE_COMMAND_H

#include <QUndoCommand>

#include "../LevelMaster2000.h"
#include "QtGroupBoxPropertyBrowser.h"
#include "QtPropertyManager.h"

#include "../Logger.h"

//Command for changing a property in the property browser.
template<class Type, class PropertyManager>
class PropertyChangeCommand : public QUndoCommand
{
public:
        PropertyChangeCommand( //LevelMaster2000* lm2k,
                //QString entityName,
		QtGroupPropertyManager *groupManager,
		PropertyManager *propertyManager, 
		QString componentName,
		QtProperty *property, 
		const Type &oldValue, 
		QUndoCommand *parent = 0 )
		: QUndoCommand( parent ),
//		lm2k( lm2k ),
                //entityName( entityName ),
		groupManager( groupManager ),
		propertyManager( propertyManager ),
		componentName( componentName ),
		oldValue( oldValue )
	{
		newValue = propertyManager->value( property );
		propertyName = property->propertyName();
	}

	void undo()
	{
		LevelMaster2000::DISALLOW_NEW_COMMAND++;
		{
                    //TODO: is this selectEntity really needed?
			//TODO: this breaks the current selection.
			//if ( lm2k->getSelectedEntities()[0] != entityName )
			{
				QStringList comps;
				comps << componentName;
				//lm2k->selectComponents( entityName, comps ); 
                                //lm2k->selectEntity( entityName );
			}
			QtProperty* property = findProperty( componentName, propertyName );
			propertyManager->setValue( property, oldValue );
			setText( propertyName );
		}
		LevelMaster2000::DISALLOW_NEW_COMMAND--;
	}

	void redo()
	{
		LevelMaster2000::DISALLOW_NEW_COMMAND++;
		{
                    //TODO: is this selectEntity really needed?
			//if ( lm2k->getSelectedEntities()[0] != entityName )
			{
								QStringList comps;
				comps << componentName;
				//lm2k->selectComponents( entityName, comps );
                                //lm2k->selectEntity( entityName );
			}
			QtProperty* property = findProperty( componentName, propertyName );
			propertyManager->setValue( property, newValue );
			setText( propertyName );
		}
		LevelMaster2000::DISALLOW_NEW_COMMAND--;
	}

	QtProperty* findProperty( QString componentName, QString propertyName )
	{
		QtProperty* property = 0;
		QSet<QtProperty*> properties = groupManager->properties();
		foreach( QtProperty* prop, properties )
		{
			if( prop->propertyName() == componentName )
			{
				QList<QtProperty*> props = prop->subProperties();
				foreach( QtProperty* p, props )
				{
					QString n = p->propertyName();
					if( p->propertyName() == propertyName )
					{
						property = p;
						break;
					}
				}
			}
		}

		if( 0 == property )
		{
//			lm2k->addLogMessage( "ERROR",
//				"PropertyChangeCommand",
//				"Property not found." );
                    Logger::instance()->addLogMessage( Logger::LL_ERROR,
                                          "PropertyChangeCommand",
                                         "Property not found." );
		}

		return property;
	}

private:

        //LevelMaster2000 *lm2k;
        //QString entityName;

	QtGroupPropertyManager *groupManager;
	PropertyManager *propertyManager;

	QString propertyName;
	QString componentName;

	Type oldValue;
	Type newValue;
};

#endif
